﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DnEcuDiag.Ecus.Enums;
using DnEcuDiag.Ecus.Generic;
using DnEcuDiag.Ecus.Kwp;
using DnEcuDiag.Factories;
using NUnit.Framework;

namespace DnEcuDiag.Tests
{
    [TestFixture]
    public class ME31Tests
    {
        private KwpEcu _ecu;
        private KwpTestDevice _device;

        [TestFixtureSetUp]
        public void TestSetup()
        {
            _device = new KwpTestDevice();

            EcuDescriptor descriptor = EcuFactory.EcuList.Find(ecuDescriptor => ecuDescriptor.Name == "Bosch Motronic ME3.1");

            _ecu = EcuFactory.CreateEcu(descriptor) as KwpEcu;
            Assert.IsNotNull(_ecu);
            _ecu.DiagnosticInterface = _device;
            _ecu.Connect();
        }

        [Test]
        public void TestIdentification()
        {
            Assert.AreEqual("Bosch Motronic ME3.1", _ecu.Model);
            Assert.AreEqual("0123456789 ", _ecu.DrawingNumber);
            Assert.AreEqual("0123456789 ", _ecu.HardwareNumber);
            Assert.AreEqual("0x10", _ecu.HardwareVersionNumber);
            Assert.AreEqual("0123456789 ", _ecu.SoftwareNumber);
            Assert.AreEqual("0x85170", _ecu.SoftwareVersionNumber);
            Assert.AreEqual("01234 ", _ecu.OmologationNumber);
            Assert.AreEqual("55 AA 55 AA 55 ", _ecu.IsoCode);
            Assert.AreEqual("19 97 03 31 ", _ecu.ProductionDate);
            Assert.AreEqual("19 97 03 31 ", _ecu.ProgrammingDate);
            Assert.IsNotNull(_ecu.RpmSensor);
            Assert.AreEqual("Engine Speed", _ecu.RpmSensor.Name);
            Assert.IsNotNull(_ecu.SpeedSensor);
            Assert.AreEqual("High Resolution Vehicle Speed", _ecu.SpeedSensor.Name);
            Assert.AreEqual(InitType.Extended, _ecu.InitType);
        }

        [Test]
        public void TestActuators()
        {
            Assert.AreEqual(15, _ecu.Actuators.Count);
        }

        [Test]
        public void TestFaults()
        {
            Assert.AreNotEqual(0, _ecu.ErrorMemoryStructureDefinition.ErrorDefinitions.Count, "_ecu.ErrorMemoryStructureDefinition.Count == 0");
            Assert.AreEqual(36, _ecu.ErrorMemoryStructureDefinition.ErrorDefinitions.Count, "_ecu.ErrorMemoryStructureDefinition.Count != 36");

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Three P0100
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////			
            _device.FaultcodeList = new byte[] { 0x58, 03, 01, 00, 0xE2, 01, 00, 0xE2, 01, 00, 0xE2 };
            _device.Faultcodeinfo = new byte[13] { 0x61, 0x10, 0x01, 0x00, 0xE2, 0x1D, 0x0D, 0x00, 0x00, 0xA, 0x0A, 0x40, 0x00 };
            _ecu.ReadFaultCodes();

            Assert.AreEqual(3, _ecu.ActiveFaultCodes.Count, "_ecu.ActiveFaultCodes.Count == 3 for M.1.5.5");
            Console.WriteLine(_ecu.ActiveFaultCodes[0].FaultDescription);
            Assert.AreEqual("P0100", (_ecu.ActiveFaultCodes[0]).FaultComponent);
            Assert.AreEqual("Failed Component Code: Air Flow Meter\r\nFault Symptom: Below Minimum Limit\r\n" +
                "Warning Lamp Status: Warning Lamp Illuminated\r\nFault Test State: Test complete for this Error or not applicable." +
                "\r\nFault Code Storage State: Error Present at time of request\r\nEvent Count: 64 count\r\n" +
                "Filter Count: 0 count\r\n" +
                "Environmental Condition One: Engine Speed: 1160 rpm\r\n" +
                "Environmental Condition Two: Standardised Load: 9.75 %\r\n" +
                "Environmental Condition Three: Engine Coolant Temperature: -41 °C\r\n" +
                "Environmental Condition Four: Air Temperature: -50 °C\r\n" +
                "Environmental Condition Five: Throttle Valve Angle: 3.16 °\r\n" +
                "Environmental Condition Six: Battery Voltage: 0.94 volts\r\n",
                _ecu.ActiveFaultCodes[0].FaultDescription);

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // one P1565
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////			
            _device.FaultcodeList = new byte[] { 0x58, 01, 0x15, 0x65, 0xE8 };
            _device.Faultcodeinfo = new byte[13] { 0x61, 0x10, 0x15, 0x65, 0xE8, 0x1D, 0x0D, 0x00, 0x00, 0xA, 0x0A, 0x40, 0x00 };
            _ecu.ReadFaultCodes();

            Assert.AreEqual(1, _ecu.ActiveFaultCodes.Count, "_ecu.ActiveFaultCodes.Count == 3 for M.1.5.5");
            Console.WriteLine(_ecu.ActiveFaultCodes[0].FaultDescription);
            Assert.AreEqual("P1565", (_ecu.ActiveFaultCodes[0]).FaultComponent);
            Assert.AreEqual("Failed Component Code: Cruise lever\r\nFault Symptom: Signal Not Plausible\r\n" +
                "Warning Lamp Status: Warning Lamp Illuminated\r\nFault Test State: Test complete for this Error or not applicable." +
                "\r\nFault Code Storage State: Error Present at time of request\r\nEvent Count: 64 count\r\n" +
                "Filter Count: 0 count\r\n" +
                "Environmental Condition One: Engine Speed: 1160 rpm\r\n" +
                "Environmental Condition Two: Standardised Load: 9.75 %\r\n" +
                "Environmental Condition Three: Engine Coolant Temperature: -41 °C\r\n" +
                "Environmental Condition Four: Air Temperature: -50 °C\r\n" +
                "Environmental Condition Five: Throttle Valve Angle: 3.16 °\r\n" +
                "Environmental Condition Six: Battery Voltage: 0.94 volts\r\n",
                _ecu.ActiveFaultCodes[0].FaultDescription);

            // Test first fault code.
            /*			Assert.AreEqual("P1565",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultCode);
                        Assert.AreEqual("Cruise lever\r\nSignal Not Plausible",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).Description);
                        Assert.AreEqual(0x40,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EventCount,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EventCount");
                        Assert.AreEqual(0x0,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FilterCount,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FilterCount");
                        Assert.AreEqual(true,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).WarningLampIlluminated,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).WarningLampIlluminated");
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).BelowMinThreshold,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).BelowMinThreshold");
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).AboveMaxThreshold,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).AboveMaxThreshold");
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultSymptomAvailable,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultSymptomAvailable");	
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).NoSignal,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).NoSignal");
                        Assert.AreEqual(true,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).InvalidSignal,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).InvalidSignal");
                        Assert.AreEqual(true,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).TestComplete,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).TestComplete");
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultNotPresentAtRequest,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultNotPresentAtRequest");
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).noFaultDetectedAtRequest,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).noFaultDetectedAtRequest");
                        Assert.AreEqual(false,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultMaturing,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultMaturing");
                        Assert.AreEqual(true,((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultPresent,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).FaultPresent");
			
                        Assert.AreEqual("Engine Speed 29 rpm",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionOne,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionOne");
                        Assert.AreEqual("Standardised Load 9.75 %",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionTwo,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionTwo");
                        Assert.AreEqual("Engine Coolant Temperature -41 °C",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionThree,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionThree");
                        Assert.AreEqual("Air Temperature -50 °C",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionFour,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionFour");
                        Assert.AreEqual("Throttle Valve Angle 3.160781 °",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionFive,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionFive");
                        Assert.AreEqual("Battery Voltage 0.942 volts",((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionSix,"((KwpFaultCode)_ecu.ActiveFaultCodes[0]).EnvironmentalConditionSix");
            */
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // U1600
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////			
            _device.FaultcodeList = new byte[] { 0x58, 0x01, 0xD6, 0x00, 0xE8 };
            _device.Faultcodeinfo = new byte[13] { 0x61, 0x10, 0xD6, 0x01, 0xE8, 0x1D, 0x0D, 0x00, 0xFF, 0xA, 0x0A, 0x40, 0x00 };
            _ecu.ReadFaultCodes();

            Assert.AreEqual(1, _ecu.ActiveFaultCodes.Count, "_ecu.ActiveFaultCodes.Count == 1 for ME3.1");
            Console.WriteLine(_ecu.ActiveFaultCodes[0].FaultDescription);
            Assert.AreEqual("U1600", (_ecu.ActiveFaultCodes[0]).FaultComponent);
            Assert.AreEqual("Failed Component Code: Immobiliser\r\nFault Symptom: Signal Not Plausible\r\n" +
                "Warning Lamp Status: Warning Lamp Illuminated\r\nFault Test State: Test complete for this Error or not applicable." +
                "\r\nFault Code Storage State: Error Present at time of request\r\nEvent Count: 64 count\r\n" +
                "Filter Count: 0 count\r\n" +
                "Environmental Condition One: Engine Speed: 1160 rpm\r\n" +
                "Environmental Condition Two: Standardised Load: 9.75 %\r\n" +
                "Environmental Condition Three: Engine Coolant Temperature: -41 °C\r\n" +
                "Environmental Condition Four: Immobiliser: Not ok\r\n" +
                "Environmental Condition Four: Immobiliser: No code received or link interrupted\r\n" +
                "Environmental Condition Four: Immobiliser: Erroneous key code\r\n" +
                "Environmental Condition Four: Immobiliser: Virgin Ecu\r\n" +
                "Environmental Condition Four: Immobiliser: Engine Start Disabled\r\n" +
                "Environmental Condition Four: Immobiliser: Universal Code Received\r\n" +
                "Environmental Condition Five: Throttle Valve Angle: 3.16 °\r\n" +
                "Environmental Condition Six: Battery Voltage: 0.94 volts\r\n",
                _ecu.ActiveFaultCodes[0].FaultDescription);
        }

        [Test]
        public void TestSensors()
        {
            Assert.AreEqual(81, _ecu.Sensors.Count);
        }

        [Test]
        public void TestPerformanceMeasurment()
        {
            Assert.AreNotEqual(null, _ecu.SpeedSensor);
            Assert.AreNotEqual(null, _ecu.RpmSensor);
        }
    }
}
